﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace System.Collections.Generic
{
	public static class _IEnumerable_T_Extensions
	{
		public static string GetJoinedStrings<T>(this IEnumerable<T> This, string delimiter, bool includeEmpties, Func<T, string> toString)
		{
			StringBuilder sb = new StringBuilder();
			bool first = true;
			foreach (T t in This)
			{
				string value = toString(t);

				if (includeEmpties || !string.IsNullOrEmpty(value))
				{
					if (!first) sb.Append(delimiter);
					first = false;

					sb.Append(value);
				}
			}
			return sb.ToString();
		}
		public static string GetJoinedStrings<T>(this IEnumerable<T> This, string delimiter, bool includeEmpties, string formatString, params Func<T, object>[] getters)
		{
			return This.GetJoinedStrings(delimiter, includeEmpties, delegate(T t)
			{
				ArrayList values = new ArrayList();
				foreach (Func<T, object> getter in getters)
				{
					values.Add(getter(t));
				}
				return string.Format(formatString, values.ToArray());
			});
		}
		public static int IndexOf<T>(this IEnumerable<T> eThis, T[] search)
		{
			int k = 0, res = 0;
			foreach (T t in eThis)
			{
				if (object.Equals(t, search[k]))
				{
					++k;
					if (k >= search.Length)
						return res - k;
				}
				else
				{
					k = 0;
					if (object.Equals(t, search[k]))
						++k;
				}
				++res;
			}
			return -1;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="eThis"></param>
		/// <param name="index">The index in this array at which to start searching.</param>
		/// <param name="count">The number of items in this array, starting at <see cref="index"/>, to include in the search.</param>
		/// <param name="search"></param>
		/// <returns></returns>
		public static int IndexOfPartial<T>(this T[] eThis, int index, int count, T[] search)
		{
			int k = 0;
			for(int i = index; i < index + count; ++i)
			{
				if (object.Equals(eThis[i], search[k]))
				{
					++k;
					if (k >= search.Length)
						return i - k + 1;
				}
				else
				{
					i -= k;
					k = 0;
				}
			}
			if (k == 0)
				return -1;
			else
				return index + count - k;
		}
	}
}
